﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using BrokerBase.Lib.Client;
using BrokerBase.Lib.Tool;

namespace Broker.Service.Model
{
    public class SActiveCode
    {
        

        public static bool IsExistByCode(string code, IDbConnection cnn)
        {

            

            string sql = "select count(*) from Sale_ActiveCode where Code=@code";

            IDbCommand cmd = cnn.CreateCommand();

            cmd.CommandText = sql;

            IDbDataParameter p = cmd.CreateParameter();
            p.ParameterName = "@code";
            p.DbType = DbType.String;
            p.Size = 100;
            p.Value = code;

            cmd.Parameters.Add(p);

            int c = Convert.ToInt32(cmd.ExecuteScalar());

            return c > 0 ? true : false;
        }

       public static SActiveCode GetActiveCodeByVerify(string activeCode,RegistrantInfo registrantInfo, TerminalInfo terminalInfo,IDbConnection cnn, out string message)
       {
           if (string.IsNullOrEmpty(activeCode))
           {
               message = "激活码不能为空";
               return null;
           }

           if (terminalInfo == null)
           {
               message = "客户端信息错误";
               return null;
           }

           if (string.IsNullOrEmpty(registrantInfo.UserName))
           {
               message = "注册名不能为空";
               return null;
           }

           if (registrantInfo.PresenterName == registrantInfo.UserName)
           {
               message = "推荐不能是自己";
               return null;
           }

           if (!string.IsNullOrEmpty(registrantInfo.PresenterName) && !SClient.IsExistByName(registrantInfo.PresenterName, cnn))
           {

               message = "推荐人不存在";
               return null;
           }

           SActiveCode sac = SActiveCode.LoadByCode(activeCode, cnn);

           if (sac == null)
           {
               message = "序列号不存在";
               return null;
           }

           SClient sclient = SClient.LoadByName(registrantInfo.UserName, cnn);

           if (sclient == null)
           {
               if (sac.IsRenewal)
               {
                   message = "要续费的注册名不存在";
                   return null;
               }

               if (sac.RegTime != null)//新用户不可能使用已存在的激活码!
               {
                   message = "激活码已经被使用过";
                   return null;
               }
           }
           else
           {
               if (sac.RegTime == null)//激活码还没有注册过
               {
                   //假如不是试用用户，并且激活码不是续费
                   if (!sclient.IsTrial && !sac.IsRenewal)
                   {
                       message = "已存在的注册用户只能使用续费类型的激活码" + Environment.NewLine + "如果是新建用户请检查用户名是否存在";
                       return null;
                   }

                   if (sclient.IsTrial && sac.IsRenewal)
                   {
                       message = "试用注册用户不能使用续费类型的激活码";
                       return null;
                   }
               }
               else//用户名存在并且已经激活，首先判断用户名是否匹配，再判断机器硬件是否匹配
               {

                   string sql = "select 1 from sale_activecode  where id="+ sac.Id+ " RegistrantId=" + sclient.Id;

                   IDbCommand cmd = cnn.CreateCommand();
                   cmd.CommandText = sql;

                   object result = cmd.ExecuteScalar();

                   if (result == null)
                   {
                       message = "用户名与激活码不匹配";
                       return null;
                   }
                   else
                   {
                       if(! sac.IsHardwareMatch(terminalInfo,cnn))
                       {
                           message = "激活码已经被使用过";
                           return null;
                       }

                   }
               }
           }

           //激活码第一次注册，并且注册时间是否已经超出有效注册期
           if (sac.RegTime == null && DateTimeUtil.ChinaStandardTime > sac.SendTime.Value.AddDays(sac.RegPeriod))
           {
               message = "激活码注册时间已经过期!";
               return null;
           }

           //Client user = ac.Client;


           if (sac.RegistrantId != null )//续费的用户名必须匹配!
           {
               SClient c = sac.LoadRegistrant(cnn);
               if (c != null && c.Name != registrantInfo.UserName)
               {
                   message = "激活码与注册名不匹配";
                   return null;
               }
           }

           //假如是试用码，不允许在多台机器上注册！
           if (sac.Edition == EditionType.Evaluation )
           {
               if (sac.RegTime != null && !sac.IsHardwareMatch(terminalInfo, cnn))
               {
                   message = "该注册码已经注册过!";
                   return null;
               }

               
           }

           if (sac.Edition == EditionType.Evaluation)
           {
               
               if (sac.RegTime != null)
               {
                   if (sac.Edition == EditionType.Evaluation && sac.RegTime != null && !sac.IsHardwareMatch(terminalInfo, cnn))
                   {
                       message = "该注册码已经注册过!";
                       return null;
                   }
               }
               //同一台机器不允许多次使用试用码

               if (IsRegisteredByOtherEvaluationCode(activeCode, terminalInfo, cnn))
               {
                   message = "该客户端已经使用过试用注册码，不能多次使用!";
                   return null;
               }
           }


           message = null;
           return sac;

        }

       public static SActiveCode LoadByCode(string code, IDbConnection cnn)
       {
           string sql = "select Id,Code,IsRenewal,RegTime,Edition,SendTime,RegPeriod,RegistrantId from sale_activecode where code =@code";

           IDbCommand cmd = cnn.CreateCommand();
           cmd.CommandText = sql;

           IDbDataParameter p = cmd.CreateParameter();
           p.ParameterName = "@code";
           p.DbType = DbType.String;
           p.Size = 100;
           p.Value = code;

           cmd.Parameters.Add(p);

           IDataReader reader = cmd.ExecuteReader();

           SActiveCode sac = null;

           while (reader.Read())
           {
               sac = new SActiveCode();

               sac.Code = code;
               sac.Id = reader.GetInt32(0);
               sac.IsRenewal = reader.GetBoolean(2);
               sac.RegTime = reader.GetDateTime(3);
               sac.Edition = (EditionType)reader.GetInt32(4);
               sac.SendTime = reader.GetDateTime(5);
               sac.RegPeriod = reader.GetInt32(6);
               sac.RegistrantId = reader.GetValue(7) as int?;
           }

           reader.Close();

           return sac;

       }

       public static bool IsRegisteredByOtherEvaluationCode(string code,TerminalInfo terminalInfo,IDbConnection cnn)
       {
           string sql = "select 1  from sale_activecodereg as r inner join sale_activecode as a on r.activecodeid=a.id where a.code <> @Code and a.edition=1 and  DISKSerialNo=@DISKSerialNo and MACSerialNo=@MACSerialNo and MBSerialNo=@MBSerialNo";

           IDbCommand cmd2 = cnn.CreateCommand();
           cmd2.CommandText = sql;

           IDataParameter p2 = cmd2.CreateParameter();
           p2.ParameterName = "@DiskSerialNo";
           p2.DbType = DbType.String;
           p2.Value = terminalInfo.DISKSerialNo;
           cmd2.Parameters.Add(p2);

           IDataParameter p3 = cmd2.CreateParameter();
           p3.ParameterName = "@MacSerialNo";
           p3.DbType = DbType.String;
           p3.Value = terminalInfo.MACSerialNo;
           cmd2.Parameters.Add(p3);

           IDataParameter p4 = cmd2.CreateParameter();
           p4.ParameterName = "@MbSerialNo";
           p4.DbType = DbType.String;
           p4.Value = terminalInfo.MBSerialNo;
           cmd2.Parameters.Add(p4);

           IList<string> ls = new List<string>();

           object result= cmd2.ExecuteScalar();

           return result==null?false:true;

       }


       public SActiveCodeReg Register(RegistrantInfo registrantInfo, TerminalInfo terminalInfo, string ipAddress, IDbConnection cnn, out string message)
       {
           SClient client=null;

           bool isNewUser = false;

           if (!SClient.IsExistByName(registrantInfo.UserName, cnn))
           {
               SClient presenter = null;

               if (string.IsNullOrEmpty(registrantInfo.PresenterName))
               {
                   presenter = SClient.LoadByName(registrantInfo.PresenterName, cnn);
               }

               //插入一个新用户
               string sql = @"insert into sale_client(ParentId,Name,LicenseCode,EMail,CreateDate,Leaf,InviteCodeQty,Level,RegTime)
                                values(@ParentId,@Name,@LicenseCode,@EMail,@CreateDate,1,@InviteCodeQty,@Level,@RegTime)";

               IDbTransaction tx = cnn.BeginTransaction();

               IDbCommand cmd = cnn.CreateCommand();
               cmd.Transaction = tx;
               cmd.CommandText = sql;

               DateTime dt = DateTimeUtil.ChinaStandardTime;

               IDbDataParameter p1 = cmd.CreateParameter();
               p1.ParameterName = "@ParentId";
               p1.DbType = DbType.Int32;
               if (presenter == null)
                   p1.Value = null;
               else
                   p1.Value = presenter.Id;
               cmd.Parameters.Add(p1);

               IDbDataParameter p2 = cmd.CreateParameter();
               p1.ParameterName = "@Name";
               p1.DbType = DbType.Int32;
               p1.Value = registrantInfo.UserName;
               cmd.Parameters.Add(p2);

               IDbDataParameter p3 = cmd.CreateParameter();
               p3.ParameterName = "@LicenseCode";
               p3.DbType = DbType.Int32;
               p3.Value = Guid.NewGuid().ToString();
               cmd.Parameters.Add(p3);

               IDbDataParameter p4 = cmd.CreateParameter();
               p4.ParameterName = "@EMail";
               p4.DbType = DbType.Int32;
               p4.Value = registrantInfo.EMail;
               cmd.Parameters.Add(p4);

               IDbDataParameter p5 = cmd.CreateParameter();
               p5.ParameterName = "@CreateDate";
               p5.DbType = DbType.Int32;
               p5.Value = dt;
               cmd.Parameters.Add(p5);

               IDbDataParameter p6 = cmd.CreateParameter();
               p6.ParameterName = "@InviteCodeQty";
               p6.DbType = DbType.Int32;
               p6.Value = presenter.Id;
               cmd.Parameters.Add(p6);

               IDbDataParameter p7 = cmd.CreateParameter();
               p7.ParameterName = "@Level";
               p7.DbType = DbType.Int32;
               p7.Value = presenter == null ? 1 : presenter.Level + 1;
               cmd.Parameters.Add(p7);

               IDbDataParameter p8 = cmd.CreateParameter();
               p8.ParameterName = "@Level";
               p8.DbType = DbType.Int32;
               p8.Value = dt;
               cmd.Parameters.Add(p8);


               cmd.ExecuteNonQuery();

               sql = "update sale_client set Leaf=0 where id=" + presenter.Id;
               cmd.Parameters.Clear();
               cmd.CommandText = sql;
               cmd.ExecuteNonQuery();

               isNewUser = true;
           }

           client = SClient.LoadByName(registrantInfo.UserName,cnn);

           message = null;

           return null;

       }

       public  bool IsHardwareMatch(TerminalInfo terminalInfo, IDbConnection cnn)
       {
           string sql2 = "select 1 from sale_activecodereg where acticecodeid=@ActiveCodeId and DISKSerialNo=@DiskSerialNo or MACSerialNo=@MacSerialNo or MbSerialNo=@MbSerialNo";

           IDbCommand cmd2 = cnn.CreateCommand();
           cmd2.CommandText = sql2;

           IDataParameter p1 = cmd2.CreateParameter();
           p1.ParameterName = "@ActiveCodeId";
           p1.DbType = DbType.Int32;
           p1.Value = this.Id;
           cmd2.Parameters.Add(p1);


           IDataParameter p2 = cmd2.CreateParameter();
           p2.ParameterName = "@DiskSerialNo";
           p2.DbType = DbType.String;
           p2.Value = terminalInfo.DISKSerialNo;
           cmd2.Parameters.Add(p2);

           IDataParameter p3 = cmd2.CreateParameter();
           p3.ParameterName = "@MacSerialNo";
           p3.DbType = DbType.String;
           p3.Value = terminalInfo.MACSerialNo;
           cmd2.Parameters.Add(p3);

           IDataParameter p4 = cmd2.CreateParameter();
           p4.ParameterName = "@MbSerialNo";
           p4.DbType = DbType.String;
           p4.Value = terminalInfo.MBSerialNo;
           cmd2.Parameters.Add(p4);

           object m = cmd2.ExecuteScalar();

           return m == null ? false : true;

        }

       public SClient LoadRegistrant(IDbConnection cnn)
       {
           if (this.RegistrantId != null)
           {
               return SClient.LoadById(this.RegistrantId.Value, cnn);
           }
           else
           {
               return null;
           }
       }

        public int Id { get; set; }

        public string Code { get; set; }

        public bool IsRenewal { get; set; }

        public EditionType Edition { get; set; }

        public DateTime? RegTime { get; set; }

        public DateTime? SendTime { get; set; }

        public int RegPeriod { get; set; }

        public int? RegistrantId { get; set; }

    }
}